import { TiktokenModel, encodingForModel } from "js-tiktoken";
export const OpenAIApi = () => {
  const { getSetValue, setSetValue } = chatSettingStore();
  const apiConfig = getSetValue("api");
  const sendMessage = async (
    messages: Message[],
    handler: (data: ExtendedChatCompletionChunk) => void,
    controller?: AbortController,
    options?: FormTemplates
  ) => {
    try {
      const max_tokens =
        options?.["max_tokens"].value ?? apiConfig("max_tokens") ?? 200000;
      const messageParams = messageHandler(messages);
      const params = {
        presence_penalty:
          options?.presence_penalty ??
          (apiConfig("presence_penalty") || undefined),
        stream: options?.presence_penalty ?? apiConfig("stream"),
        temperature:
          options?.temperature ?? (apiConfig("temperature") || undefined),
        top_p: options?.top_p ?? (apiConfig("top_p") || undefined),
        frequency_penalty:
          options?.frequency_penalty ??
          (apiConfig("frequency_penalty") || undefined),
        max_tokens: max_tokens || undefined,
        model: options?.["modelName"] ?? apiConfig("modelName") ?? "claude-2.1",
        messages: messageParams,
      };
      const { data, error } = await useDefaultRequest.post<ReadableStream, any>(
        (options?.apiUrl as unknown as string) ??
          apiConfig("apiUrl")! + "/v1/chat/completions",
        params,
        {
          headers: {
            "Content-Type": "application/json",
            Authorization: "Bearer " + apiConfig("Authorization"),
          },
          responseType: "stream",
        },
        controller
      );
      if (error && error.message !== "The user aborted a request.") {
        handler(createErrorMessage(error.message));
        return;
      }
      const enc = encodingForModel(
        modelNames.includes(apiConfig("modelName"))
          ? (options?.modelName as unknown as TiktokenModel) ?? apiConfig("modelName")
          : "gpt-3.5-turbo"
      );
      useStream(data! as ReadableStream<any>, handler);
    } catch (error: any) {
      handler(createErrorMessage(error.message));
    }
  };
  const getModelList = async () => {
    const response = await useDefaultRequest.get(
      apiConfig("apiUrl") + "/v1/models",
      null,
      {
        responseType: "json",
        headers: {
          Authorization: `Bearer ${apiConfig("Authorization")}`,
        },
      }
    );
    return response;
  };
  return { sendMessage, getModelList };
};
